Este principio consiste en que cuando tienes una interfaz con muchas funciones las cuales no son necesarias en todas las clases que implementen dicha interfaz tenemos que separar dichas funciones en varias subinterfaces, para que sean implementadas solo en las clases que realmente utilizan las funciones asociadas a la interfaz.
En este ejemplo tenemos una clase transaccion la cual tiene una serie de subclases para encapsular los distintos tipos de transacciones, a su vez cada subclase tiene que hacer uso de funciones de la clase UI para solicitar datos al usuario:
En este caso como todas las subclases de transacción hacen uso de la interfaz UI si una de las subclases necesita modificar la interfaz para añadir algún metodo nuevo todas las subclases se veran obligadas a ser recompiladas a pesar de que no haya ningún cambio en dichas clases, todas las clases están acopladas porque hacen uso de la misma interfaz.
La manera de solucionar este problema es utilizar varias interfaces para que cada subclase solo hago uso de una interfaz con métodos que solo use dicha subclase:
De esta manera estaremos cumpliendo con el principio de segregación de interfaces.
En este ejemplo tenemos una interfaz puerta (Door), la cual usaremos para crear clases que la implementen, pero una situación que se puede dar es que necesitemos un tipo de puerta que tenga alguna función exclusiva, como por ejemplo una puerta con temporizador (Timed Door), que requiere de una funcion Timeout, en este caso la interfaz Door tiene que implementar dicha interfaz (Timer Client):
Esto obliga a que todas las clases que implementen la interfaz Door tengan que implementar dicha función, a pesar de que no tengan relacion con el temporizador... por lo tanto estamos violando el ISP.
La solución a esto es hacer que solo las subclases que necesiten esta interfaz (timer client) la implementen, asi:
NOTA: tenemos que tener en cuenta que en el primer diseño Timed Door sería una clase que implementaría la interfaz Door, pero en el segundo diseño podría ser una clase o una interfaz dependiendo de si queremos hacer una abstracción, de manera que las clases clientes podrían obtar por implementar Door para obtener las funciones básicas de la clase, o si necesitasen un tipo temporizado implementar Timed Door.
De esta manera lo que hacemos es segregar la interfaz y evitar que haya subclases de Door que tengan que implementar funciones que no van a utilizar.
SOLID | Interface Segregation